<!DOCTYPE html>
<html lang="zh-CN">
    <head>
        <!-- Meta, title, CSS, favicons, etc. -->
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="description" content="avalonjs - 迷你简单易用的前端MVVM框架，让你的网站更快更炫更好用">
        <meta name="keywords" content="MVVM, CSS, JavaScript, framework, avalon, web development">
        <meta name="author" content="RubyLouvre,司徒正美">


        <title>avalon中文文档</title>
        <script src="//files.cnblogs.com/files/rubylouvre/avalon.shim.js"></script>

        <!-- Bootstrap core CSS -->
        <link href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">

        <link href="../../assets/css/patch.css" rel="stylesheet">

        <!-- Documentation extras -->

        <link href="../../assets/css/docs.min.css" rel="stylesheet">
        <style>
            body,html{
               overflow-y: hidden;
            }
        </style>
        <!--[if lt IE 9]><script src="../assets/js/ie8-responsive-file-warning.js"></script>
        <script src="../../assets/js/ie-emulation-modes-warning.js"></script>
        <![endif]-->
        <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
        <!--[if lt IE 9]>
          <script src="//cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
          <script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
        <![endif]-->

        <!-- Favicons -->
        <link rel="apple-touch-icon" href="/apple-touch-icon.png">
        <link rel="icon" href="/favicon.ico">

    </head>
    <body>




        <div class="container bs-docs-container">

            <div class="row">
                <div class="col-md-9" role="main">


<h2 id='tutorial/concepts/collection.html'>监控数组</h2>

<p>操作此数组的方法会同步视图的特殊数组，它是由VM中的数组自动转换而来。方便与ms-repeat, ms-each配合使用，
    能批量同步一大堆DOM节点。
</p>
<p>监控数组的方法与普通数组没什么不同，它只是被重写了某一部分方法，如
    pop, shift, unshift, push, splice，sort, revert。其次添加了四个移除方法，remove, removeAt, removeAll, clear，
    及ensure，pushArray, size，set方法。
</p>
<ul>
    <li>pushArray(el), 要求传入一数组，然后将它里面的元素全部到当前数组的末端。</li>
    <li>remove(el), 要求传入一元素，通过全等于比较进行移除。</li>
    <li>removeAt(index), 要求传入一数字，会移除对应位置的元素。</li>
    <li>removeAll(arrayOrFunction), 有三种用法，如果是一个函数，则过滤比较后得到真值的元素，
        如果是一数组，则将此数组中与原数组相等于的元素全部移除；如果没有任何参数，则全部清空。
    </li>
    <li>clear()，相当于removeAll()的第三种方法，清空数组的所有元素。由于需要同步视图的缘故，不能通过vm.array.length = 0的方法来清空元素。</li>
    <li>ensure(el)，只有当数组不存在此元素时，只添加此元素。</li>
    <li>size()，返回数组的长度。由于length属性是固有属性，无法hack，也就无法实现双向绑定，因此请用它来代替length。</li>
    <li>set(index, el)，用于更新某一索引位置中的元素，因为简单数组元素的数组，是不会转换它的元素。</li>
</ul>


<div ms-skip style='background:rgb(237,237,237);padding:4px;'><pre class='brush:html;gutter:false;toolbar:false'>&lt;!DOCTYPE HTML&gt;
&lt;html&gt;

&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta http-equiv="X-UA-Compatible" content="IE=edge" /&gt;
    &lt;title&gt;ms-repeat&lt;/title&gt;
    &lt;script src="avalon.js" type="text/javascript"&gt;&lt;/script&gt;

    &lt;script&gt;
        var data = {
            $id: "array",
            array: ["1", "2", "3", "4"],
            removeAt: function(e) {
                if (isFinite(this.value) && e.which == 13) { //this为input元素
                    var a = ~~this.value
                    vm.array.removeAt(a)
                    this.value = "";
                }
            }
        }

        "push,unshift,remove,ensure".replace(/\w+/g, function(method) {
            data[method] = function(e) {
                if (this.value && e.which == 13) { //this为input元素
                    vm.array[method](this.value);
                    this.value = "";
                }
            }
        })
        "pop,shift,sort,reverse".replace(/\w+/g, function(method) {
            data[method] = function(e) {
                vm.array[method]();
            }
        })

        var vm = avalon.define(data) //avalon1.5这样定义VM

        if (!Date.now) {
            Date.now = function() {
                return new Date - 0;
            }
        }
        var vm2 = avalon.define({
            $id: "c-collection2",
            selected: "name",
            options: ["name", "size", "date"],
            trend: 1,
            data: [{
                name: "aaa",
                size: 213,
                date: Date.now() + 20
            }, {
                name: "bbb",
                size: 4576,
                date: new Date - 4
            }, {
                name: "ccc",
                size: 563,
                date: new Date - 7
            }, {
                name: "eee",
                size: 3713,
                date: 9 + Date.now()
            }, {
                name: "555",
                size: 389,
                date: Date.now() - 20
            }]
        })
        vm2.$watch("selected", function(v) {
            var t = parseFloat(vm2.trend)
            vm2.data.sort(function(a, b) {
                var ret = a[v] &gt; b[v] ? 1 : -1
                return t * ret
            })
        })
        vm2.$watch("trend", function(t) {
            var v = vm2.selected,
                t = parseFloat(t)
            vm2.data.sort(function(a, b) {
                var ret = a[v] &gt; b[v] ? 1 : -1
                return t * ret
            })
        })
    &lt;/script&gt;
&lt;/head&gt;

&lt;body&gt;
    &lt;fieldset ms-controller="array"&gt;
        &lt;legend&gt;示例一&lt;/legend&gt;
        &lt;ul&gt;
            &lt;li ms-repeat="array"&gt;数组的第{{$index+1}}个元素为{{el}}&lt;/li&gt;
        &lt;/ul&gt;
        &lt;div&gt;对数组进行push操作，并回车
            &lt;input ms-keypress="push"&gt;
        &lt;/div&gt;
        &lt;div&gt;对数组进行unshift操作，并回车
            &lt;input ms-keypress="unshift"&gt;
        &lt;/div&gt;
        &lt;div&gt;对数组进行ensure操作，并回车
            &lt;input ms-keypress="ensure"&gt;
            &lt;br/&gt; (只有数组不存在此元素才push进去)
        &lt;/div&gt;
        &lt;div&gt;对数组进行remove操作，并回车
            &lt;input ms-keypress="remove"&gt;
        &lt;/div&gt;
        &lt;div&gt;对数组进行removeAt操作，并回车
            &lt;input ms-keypress="removeAt"&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;button type="button" ms-click="sort"&gt;对数组进行sort操作&lt;/button&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;button type="button" ms-click="reverse"&gt;对数组进行reverse操作&lt;/button&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;button type="button" ms-click="shift"&gt;对数组进行shift操作&lt;/button&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;button type="button" ms-click="pop"&gt;对数组进行pop操作&lt;/button&gt;
        &lt;/div&gt;
        &lt;div&gt;当前数组的长度为&lt;span style="color:red"&gt;{{array.size()}}&lt;/span&gt;&lt;/div&gt;
    &lt;/fieldset&gt;
    &lt;fieldset ms-controller="c-collection2"&gt;
        &lt;legend&gt;示例二&lt;/legend&gt;
        &lt;p&gt;
            &lt;select ms-duplex="selected"&gt;
                &lt;option ms-repeat="options"&gt;{{el}}&lt;/option&gt;
            &lt;/select&gt;
            &lt;select ms-duplex="trend"&gt;
                &lt;option value="1"&gt;up&lt;/option&gt;
                &lt;option value="-1"&gt;down&lt;/option&gt;
            &lt;/select&gt;
        &lt;/p&gt;
        &lt;table width="500px" border="1"&gt;
            &lt;tbody&gt;
                &lt;tr ms-repeat="data"&gt;
                    &lt;td&gt;{{el.name}}&lt;/td&gt;
                    &lt;td&gt;{{el.size}}&lt;/td&gt;
                    &lt;td&gt;{{el.date}}&lt;/td&gt;
                &lt;/tr&gt;
            &lt;/tbody&gt;
        &lt;/table&gt;
    &lt;/fieldset&gt;
&lt;/body&gt;

&lt;/html&gt;</pre></div>   

<fieldset ms-controller="array">
    <legend>示例一</legend>
    <ul >
        <li ms-repeat="array">数组的第{{$index+1}}个元素为{{el}}</li>
    </ul>
    <div>对数组进行push操作，并回车<input ms-keypress="push"></div>
    <div>对数组进行unshift操作，并回车<input ms-keypress="unshift"></div>
    <div>对数组进行ensure操作，并回车<input ms-keypress="ensure"><br/>
        (只有数组不存在此元素才push进去)</div>
    <div>对数组进行remove操作，并回车<input ms-keypress="remove"></div>
    <div>对数组进行removeAt操作，并回车<input ms-keypress="removeAt"></div>
    <div><button type="button" ms-click="sort">对数组进行sort操作</button></div>
    <div><button type="button" ms-click="reverse">对数组进行reverse操作</button></div>
    <div><button type="button" ms-click="shift">对数组进行shift操作</button></div>
    <div><button type="button" ms-click="pop">对数组进行pop操作</button></div>
    <div>当前数组的长度为<span style="color:red">{{array.size()}}</span></div>
</fieldset>
<div class="bs-callout bs-callout-warning">
   注意 我们无法修改数组length的固有行为，因此它无法同步视图，需要用size方法。
</div>
<fieldset ms-controller="c-collection2">
    <legend>示例二</legend>
    <p><select ms-duplex="selected">
            <option ms-repeat="options">{{el}}</option>
        </select>
        <select ms-duplex="trend">
            <option value="1">up</option>
            <option value="-1">down</option>
        </select>
    </p>
    <table width="500px" border="1">
        <tbody>
            <tr ms-repeat="data">
                <td>{{el.name}}</td> <td>{{el.size}}</td> <td>{{el.date}}</td>
            </tr>
        </tbody>
    </table>
</fieldset>
<script>
    var data = {
        $id: "array",
        array: ["1", "2", "3", "4"],
        removeAt: function (e) {
            if (isFinite(this.value) && e.which == 13) {//this为input元素
                var a = ~~this.value
                vm.array.removeAt(a)
                this.value = "";
            }
        }
    }

    "push,unshift,remove,ensure".replace(/\w+/g, function (method) {
        data[method] = function (e) {
            if (this.value && e.which == 13) {//this为input元素
                vm.array[method](this.value);
                this.value = "";
            }
        }
    })
    "pop,shift,sort,reverse".replace(/\w+/g, function (method) {
        data[method] = function (e) {
            vm.array[method]();
        }
    })

    var vm = avalon.define(data)

    if (!Date.now) {
        Date.now = function () {
            return new Date - 0;
        }
    }
    var vm2 = avalon.define({
        $id: "c-collection2",
        selected: "name",
        options: ["name", "size", "date"],
        trend: 1,
        data: [
            {name: "aaa", size: 213, date: Date.now() + 20},
            {name: "bbb", size: 4576, date: new Date - 4},
            {name: "ccc", size: 563, date: new Date - 7},
            {name: "eee", size: 3713, date: 9 + Date.now()},
            {name: "555", size: 389, date: Date.now() - 20}
        ]
    })
    vm2.$watch("selected", function (v) {
        var t = parseFloat(vm2.trend)
        vm2.data.sort(function (a, b) {
            var ret = a[v] > b[v] ? 1 : -1
            return t * ret
        })
    })
    vm2.$watch("trend", function (t) {
        var v = vm2.selected, t = parseFloat(t)
        vm2.data.sort(function (a, b) {
            var ret = a[v] > b[v] ? 1 : -1
            return t * ret
        })
    })
</script>

</div>
<div class="col-md-3" role="complementary">

</div>
</div>
</div>
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
<script src="../../assets/highlight/shCore.js"></script>

<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../assets/js/ie10-viewport-bug-workaround.js"></script>
</body>
</html>

